/**
 ******************************************************************************
 * @file    
 * @author 
 * @Version 
 * @Date    
 * @brief 
 *******************************************************************************  
 **/
#include "zb32l03x_hal.h"
#include "bsp_powerctrl.h"
#include "app_powerctrl.h"
#include "log.h"
static ADC_HandleTypeDef       POWERADC_HandleStruct = {0};
static  HAL_VC_HandleTypeDef        VC_HandleTypeDef = {0};

/*
*********************************************************************************************************
*	功能说明: 初始化
*	形    参: 
*	返 回 值: 
* 说    明：
*********************************************************************************************************
*/

void bsp_powerctrl_init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
   

    BSP_POWERCTRL_POWEREN_CLKENABLE();
    
    GPIO_InitStruct.Pin = BSP_POWERCTRL_POWEREN_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT;
    GPIO_InitStruct.Debounce.Enable = GPIO_DEBOUNCE_DISABLE;
    GPIO_InitStruct.SlewRate = GPIO_SLEW_RATE_HIGH;
    GPIO_InitStruct.DrvStrength = GPIO_DRV_STRENGTH_HIGH;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(BSP_POWERCTRL_POWEREN_PORT, &GPIO_InitStruct);
    BSP_POWERCTRL_POWEROFF();

    BSP_POWERCTRL_EXPOWER_CLKENABLE();
    GPIO_InitStruct.Pin = BSP_POWERCTRL_EXPOWER_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Debounce.Enable = GPIO_DEBOUNCE_DISABLE;
    GPIO_InitStruct.SlewRate = GPIO_SLEW_RATE_HIGH;
    GPIO_InitStruct.DrvStrength = GPIO_DRV_STRENGTH_HIGH;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(BSP_POWERCTRL_EXPOWER_PORT, &GPIO_InitStruct);

    BSP_POWERCTRL_SYSPOWER_CLKENABLE();
    GPIO_InitStruct.Pin = BSP_POWERCTRL_SYSPOWER_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT;
    GPIO_InitStruct.Debounce.Enable = GPIO_DEBOUNCE_DISABLE;
    GPIO_InitStruct.SlewRate = GPIO_SLEW_RATE_HIGH;
    GPIO_InitStruct.DrvStrength = GPIO_DRV_STRENGTH_HIGH;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(BSP_POWERCTRL_SYSPOWER_PORT, &GPIO_InitStruct);
    BSP_POWERCTRL_SYSPOWEROFF();

    BSP_POWERCTRL_BATTER_VAL_CLKENABLE();
    GPIO_InitStruct.Pin             = BSP_POWERCTRL_BATTER_VAL_PIN;
    GPIO_InitStruct.Mode            = GPIO_MODE_ANALOG;
    GPIO_InitStruct.OpenDrain       = GPIO_OPENDRAIN;
    GPIO_InitStruct.Debounce.Enable = GPIO_DEBOUNCE_DISABLE;
    GPIO_InitStruct.SlewRate        = GPIO_SLEW_RATE_HIGH;
    GPIO_InitStruct.DrvStrength     = GPIO_DRV_STRENGTH_HIGH;
    GPIO_InitStruct.Pull            = GPIO_NOPULL;
    HAL_GPIO_Init(BSP_POWERCTRL_BATTER_VAL_PORT, &GPIO_InitStruct);

    BSP_POWERCTRL_POWER_VAL_CLKENABLE();
    GPIO_InitStruct.Pin             = BSP_POWERCTRL_POWER_VAL_PIN;
    GPIO_InitStruct.Mode            = GPIO_MODE_ANALOG;
    GPIO_InitStruct.OpenDrain       = GPIO_OPENDRAIN;
    GPIO_InitStruct.Debounce.Enable = GPIO_DEBOUNCE_DISABLE;
    GPIO_InitStruct.SlewRate        = GPIO_SLEW_RATE_HIGH;
    GPIO_InitStruct.DrvStrength     = GPIO_DRV_STRENGTH_HIGH;
    GPIO_InitStruct.Pull            = GPIO_NOPULL;
    HAL_GPIO_Init(BSP_POWERCTRL_POWER_VAL_PORT, &GPIO_InitStruct);

    BSP_POWERCTRL_SHORTDET_CLKENABLE();
    GPIO_InitStruct.Pin             = BSP_POWERCTRL_SHORTDET_PIN;
    GPIO_InitStruct.Mode            = GPIO_MODE_AF;
    GPIO_InitStruct.Alternate             = BSP_POWERCTRL_SHORTDET_FUN;
    GPIO_InitStruct.OpenDrain       = GPIO_OPENDRAIN;
    GPIO_InitStruct.Debounce.Enable = GPIO_DEBOUNCE_DISABLE;
    GPIO_InitStruct.SlewRate        = GPIO_SLEW_RATE_HIGH;
    GPIO_InitStruct.DrvStrength     = GPIO_DRV_STRENGTH_HIGH;
    GPIO_InitStruct.Pull            = GPIO_NOPULL;
    //HAL_GPIO_Init(BSP_POWERCTRL_SHORTDET_PORT, &GPIO_InitStruct);


    BSP_POWERCTRL_SHORTFLAG_CLKENABLE();
    GPIO_InitStruct.Pin             = BSP_POWERCTRL_SHORTFLAG_PIN;
    GPIO_InitStruct.Mode            = GPIO_MODE_AF;
    GPIO_InitStruct.Alternate             = BSP_POWERCTRL_SHORTFLAG_FUN;
    GPIO_InitStruct.OpenDrain       = GPIO_OPENDRAIN;
    GPIO_InitStruct.Debounce.Enable = GPIO_DEBOUNCE_DISABLE;
    GPIO_InitStruct.SlewRate        = GPIO_SLEW_RATE_HIGH;
    GPIO_InitStruct.DrvStrength     = GPIO_DRV_STRENGTH_HIGH;
    GPIO_InitStruct.Pull            = GPIO_NOPULL;
    HAL_GPIO_Init(BSP_POWERCTRL_SHORTFLAG_PORT, &GPIO_InitStruct);

    __HAL_RCC_LVDVC_CLK_ENABLE(); // VC Clock enable

    VC_HandleTypeDef.Instance           = (VC_TypeDef*)VC0;
    VC_HandleTypeDef.Init.NInChannelSel = HAL_VC_IN_CHANNEL_DACO;
    VC_HandleTypeDef.Init.PInChannelSel = HAL_VC_IN_CHANNEL_5;
    VC_HandleTypeDef.Init.Fliter_Num    = 0xff;
    VC_HandleTypeDef.Init.Filter_Clk    = HAL_VC_FILTER_CLK_PCLK;
    VC_HandleTypeDef.Init.FilterEnable  = true;
    VC_HandleTypeDef.Init.InterruptMode = HAL_VC_INTERRUPT_TRIGGER_FALL|HAL_VC_INTERRUPT_TRIGGER_RISE;
    VC_HandleTypeDef.Init.Vref     = HAL_VC_DAC_VREF_VCAP;
    VC_HandleTypeDef.Init.DACLevel = 20;//3300*25/64=1031mV

    
    HAL_NVIC_SetPriority(VC0_1_IRQn, PRIORITY_LOW);
    HAL_NVIC_EnableIRQ(VC0_1_IRQn); //NVIC Interrupt enable
    

    __HAL_RCC_ADC_CLK_ENABLE();
    POWERADC_HandleStruct.Instance                = ADC;
    POWERADC_HandleStruct.Init.SamplingTime       = HAL_ADC_SAMPLE_8CYCLE;
    POWERADC_HandleStruct.Init.AChannelSel        = BSP_POWERCTRL_POWER_VAL_CH;
    POWERADC_HandleStruct.Init.ClkSel             = HAL_ADC_CLOCK_PCLK_DIV4;
    POWERADC_HandleStruct.Init.ConvMode           = HAL_ADC_MODE_SINGLE;
    POWERADC_HandleStruct.Init.AutoAccumulation   = HAL_ADC_AUTOACC_DISABLE;
    POWERADC_HandleStruct.Init.CircleMode         = HAL_ADC_MULTICHANNEL_NONCIRCLE;
    POWERADC_HandleStruct.Init.Vref               = HAL_ADC_VREF_VDD;
    POWERADC_HandleStruct.Init.ExtTrigConv0       = HAL_ADC_EXTTRIG_SW_START;
    

    
    bsp_powerctrl_closevc();
    
    
}

/*
*********************************************************************************************************
*	功能说明: 打开vc检测
*	形    参: 
*	返 回 值: 
*   说    明：
*********************************************************************************************************
*/

void bsp_powerctrl_openvc(uint32_t flag)
{
  VC_HandleTypeDef.Init.InterruptMode =  flag;
  if(VC_HandleTypeDef.Init.InterruptMode == HAL_VC_INTERRUPT_TRIGGER_FALL)//检测短路
  {
    VC_HandleTypeDef.Init.DACLevel = 20;//3300*25/64=1031mV
  }
  else//检测短路恢复
  {
     VC_HandleTypeDef.Init.DACLevel = 30;//3300*30/64=1546mV
  }
  HAL_VC_Init(&VC_HandleTypeDef);
  HAL_VC_Start_IT(&VC_HandleTypeDef);   
}

/*
*********************************************************************************************************
*	功能说明: 关闭vc检测
*	形    参: 
*	返 回 值: 
*   说    明：
*********************************************************************************************************
*/

void bsp_powerctrl_closevc(void)
{
  
  HAL_VC_Init(&VC_HandleTypeDef);
  HAL_VC_Stop_IT(&VC_HandleTypeDef);   
}




/*
*********************************************************************************************************
*	功能说明: 获取输出电压
*	形    参: 
*	返 回 值: 
* 说    明：
*********************************************************************************************************
*/
uint16_t  bsp_powerctrl_getpowervalue(void)
{
   POWERADC_HandleStruct.Init.AChannelSel        = BSP_POWERCTRL_POWER_VAL_CH;
   HAL_ADC_Init(&POWERADC_HandleStruct);
   HAL_ADC_Start(&POWERADC_HandleStruct);
   while( __HAL_ADC_IS_BUSY(&POWERADC_HandleStruct) ) {}
   return HAL_ADC_GetValue(&POWERADC_HandleStruct, POWERADC_HandleStruct.Init.AChannelSel); 
}

/*
*********************************************************************************************************
*	功能说明: 获取电池电量
*	形    参: 
*	返 回 值: 
* 说    明：
*********************************************************************************************************
*/
uint16_t  bsp_powerctrl_getbattervalue(void)
{
   POWERADC_HandleStruct.Init.AChannelSel        = BSP_POWERCTRL_BATTER_VAL_CH;
   HAL_ADC_Init(&POWERADC_HandleStruct);
   HAL_ADC_Start(&POWERADC_HandleStruct);
   while( __HAL_ADC_IS_BUSY(&POWERADC_HandleStruct) ) {}
   return HAL_ADC_GetValue(&POWERADC_HandleStruct, POWERADC_HandleStruct.Init.AChannelSel);  
}


/*
*********************************************************************************************************
*	功能说明: 比较器中断
*	形    参: 
*	返 回 值: 
*  说    明：
*********************************************************************************************************
*/

void VC0_1_IRQHandler(void)
{

    HAL_VC_IRQHandler(&VC_HandleTypeDef);
    return;
}

void HAL_VC_FilterCmpltCallback(HAL_VC_HandleTypeDef *hvc)
{
    if (hvc->Instance == (VC_TypeDef *)VC0)
    {
     // 短路，关闭电源
     if (VC_HandleTypeDef.Init.InterruptMode == HAL_VC_INTERRUPT_TRIGGER_FALL)
     {
       app_powerctrl_short(1);
     }
     else
     {
       app_powerctrl_short(0);
     }
    }
    return;
}
